package visiopuce.service.document;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;

import visiopuce.ApplicationContexte;
import visiopuce.objets.Analyse;
import visiopuce.objets.Champ;
import visiopuce.objets.FeuillePuce;
import visiopuce.objets.Personne;
import visiopuce.objets.Prelevement;
import visiopuce.objets.Puce;
import visiopuce.service.AnalyseServiceImpl;
import visiopuce.service.PersonneServiceImpl;
import visiopuce.service.PrelevementServiceImpl;
import visiopuce.service.PuceServiceImpl;

public class ProtocolePuce {

	public String createDocument(FeuillePuce fp) {
		String nomFichierOut = "";
		String[] index = { "1_1", "1_2", "1_3", "1_4", "2_1", "2_2", "2_3", "2_4" };
		try {

			boolean creer = true;
			FileInputStream file = new FileInputStream(new File(ApplicationContexte.REPERTOIRE_MODEL + "protocoles\\puce\\" + fp.getProtocole()));
			SimpleDateFormat formatterEN = new SimpleDateFormat("yyyy.MM.dd");
			SimpleDateFormat formatterFR = new SimpleDateFormat("dd/MM/yyyy");

			String typePuce = "";
			if (fp.getProtocole().contains("180k")) {
				typePuce = "4x180K";
			} else if (fp.getProtocole().contains("60k")) {
				typePuce = "8x60K";
			}
			nomFichierOut = ApplicationContexte.REPERTOIRE_PROTOCOLE + formatterEN.format(fp.getDateEnvoi()) + " - N°" + fp.getIdFeuillePuce() + " - " + typePuce + ".xls";

			File fileout = new File(nomFichierOut);
			if (fileout.exists()) {
				creer = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Fichier existant", "Le fichier " + fileout.getName() + " existe déjà souhaitez vous l'écraser?");
			}
			HashMap<String, Puce> puces = PuceServiceImpl.getInstance().getPuceFromFeuillePuce(fp.getIdFeuillePuce());
			HashMap<String, Analyse> analyses = new HashMap<String, Analyse>(puces.size());
			HashMap<String, Prelevement> prelevements = new HashMap<String, Prelevement>(puces.size());
			HashMap<String, Personne> personnes = new HashMap<String, Personne>(puces.size());
			HashMap<String, Champ> rangements = new HashMap<String, Champ>(puces.size());
			HashMap<String, Champ> concentrations = new HashMap<String, Champ>(puces.size());
			int i = 0;
			for (Entry<String, Puce> ent : puces.entrySet()) {
				String numeroOrdre = ent.getKey();
				Puce puce = ent.getValue();
				analyses.put(numeroOrdre, AnalyseServiceImpl.getInstance().getAnalyseByIdAnalyse(puce.getAnalyse().getIdAnalyse()));
				prelevements.put(numeroOrdre, PrelevementServiceImpl.getInstance().getPrelevementById(analyses.get(numeroOrdre).getPrelevement().getIdPrelevement()));
				Personne personne = PersonneServiceImpl.getInstance().getPersonneById(prelevements.get(numeroOrdre).getPersonne().getIdPersonne());
				personnes.put(numeroOrdre, personne);
				boolean reponse = false;
				boolean purif = false;
				Champ cRangementPurif = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tRangementADNpurif", "Prel-" + prelevements.get(numeroOrdre).getIdPrelevement());
				Champ cConcentrationPurif = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tConcentrationADNpurif", "Prel-" + prelevements.get(numeroOrdre).getIdPrelevement());
				Champ cRangement = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tRangementADN", "Prel-" + prelevements.get(numeroOrdre).getIdPrelevement());
				Champ cConcentration = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tConcentrationADN", "Prel-" + prelevements.get(numeroOrdre).getIdPrelevement());

				Champ ctypeADN = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tTypeADN", "Prel-" + prelevements.get(numeroOrdre).getIdPrelevement());
				if (ctypeADN != null) {
					if (ctypeADN.getValeur().equals("Extraction et Purification")) {
						reponse = MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Attention", "Une extraction et une purification existent pour le dossier " + personne.getNom() + " " + personne.getPrenom()
								+ ", souhaitez-vous utiliser la purification pour faire la puce? (annuler = utiliser l'extraction, ok = utiliser la purification)");
						if (reponse) {
							if (cRangementPurif != null) {
								rangements.put(numeroOrdre, cRangementPurif);
							} else {
								MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "Le rangement de l'ADN purifié pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
							}
							if (cConcentrationPurif != null) {
								concentrations.put(numeroOrdre, cConcentrationPurif);
							} else {
								MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "La concentration de l'ADN purifié pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
							}
							purif = true;
						} else {
							if (cRangement != null) {
								rangements.put(numeroOrdre, cRangement);
							} else {
								MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "Le rangement de l'ADN extrait pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
							}
							if (cConcentration != null) {
								concentrations.put(numeroOrdre, cConcentration);
							} else {
								MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "La concentration de l'ADN extrait pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
							}
							purif = false;
						}
					}
					if (ctypeADN.getValeur().equals("Purification")) {
						if (cRangementPurif != null) {
							rangements.put(numeroOrdre, cRangementPurif);
						} else {
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "Le rangement de l'ADN purifié pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
						}
						if (cConcentrationPurif != null) {
							concentrations.put(numeroOrdre, cConcentrationPurif);
						} else {
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "La concentration de l'ADN purifié pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
						}
						purif = true;
					}
					if (ctypeADN.getValeur().equals("Extraction")) {
						if (cRangement != null) {
							rangements.put(numeroOrdre, cRangement);
						} else {
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "Le rangement de l'ADN extrait pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
						}
						if (cConcentration != null) {
							concentrations.put(numeroOrdre, cConcentration);
						} else {
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "La concentration de l'ADN extrait pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
						}
						purif = false;
					}
				} else {
					if (cRangementPurif != null) {
						rangements.put(numeroOrdre, cRangementPurif);

					} else if (cRangement != null) {
						rangements.put(numeroOrdre, cRangement);
					} else {
						MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "Le rangement de l'ADN pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
					}
					if (cConcentrationPurif != null) {
						concentrations.put(numeroOrdre, cConcentrationPurif);
						purif = true;
					} else if (cConcentration != null) {
						concentrations.put(numeroOrdre, cConcentration);
						purif = false;
					} else {
						MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Attention", "La concentration de l'ADN pour le dossier " + personne.getNom() + " " + personne.getPrenom() + " n'est pas indiqué!");
					}

				}
				String txt = "";
				if (puce.getParametres() == null || puce.getParametres().isEmpty()) {
					if (purif) {
						txt = "ADN utilisé pour la puce : ADN purifié\r\n";
					} else {
						txt = "ADN utilisé pour la puce : ADN extrait non purifié\r\n";
					}
					puce.setParametres(txt);
				}

				PuceServiceImpl.getInstance().save(puce);
				i++;
			}
			if (creer) {
				// Get the workbook instance for XLS file
				HSSFWorkbook workbook = new HSSFWorkbook(file);
				FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
				// Get first sheet from the workbook
				HSSFSheet sheet = workbook.getSheetAt(0);

				// Iterate through each rows from first sheet
				Iterator<Row> rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) {
					Row row = rowIterator.next();

					// For each row, iterate through each columns
					Iterator<Cell> cellIterator = row.cellIterator();
					while (cellIterator.hasNext()) {

						Cell cell = cellIterator.next();
						if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
							if (cell.getStringCellValue().contains("Fiche de travail N°")) {
								cell.setCellValue("Fiche de travail N°" + fp.getIdFeuillePuce() + " du " + formatterFR.format(fp.getDateEnvoi()));
							}
							if (cell.getStringCellValue().contains("$dateManip")) {
								cell.setCellValue(formatterFR.format(fp.getDateEnvoi()));
							}
							if (cell.getStringCellValue().equals("$operateur")) {
								cell.setCellValue(fp.getOperateur().getPrenom() + " " + fp.getOperateur().getNom());
							}

							if (cell.getStringCellValue().contains("$nom")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && personnes.containsKey(index[nb - 1])) {
									cell.setCellValue(personnes.get(index[nb - 1]).getNom());
								}
							}
							if (cell.getStringCellValue().contains("$prenom")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && personnes.containsKey(index[nb - 1])) {
									cell.setCellValue(personnes.get(index[nb - 1]).getPrenom());
								}
							}
							if (cell.getStringCellValue().contains("$numero")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && prelevements.containsKey(index[nb - 1])) {
									cell.setCellValue(prelevements.get(index[nb - 1]).getNumeroPrelevement());
								}
							}
							if (cell.getStringCellValue().contains("$sexe")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && personnes.containsKey(index[nb - 1])) {
									if (prelevements.get(index[nb - 1]).getSecteur().getLibelle().contains("rénatale")) {
										Champ cSexeFoetus = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tSexeFoetus", "Prel-" + prelevements.get(index[nb - 1]).getIdPrelevement());
										if (cSexeFoetus != null) {
											if (cSexeFoetus.getValeur().equals("M")) {
												cell.setCellValue("Male");
											} else if (cSexeFoetus.getValeur().equals("F")) {
												cell.setCellValue("Femme");
											} else {
												MessageDialog.openError(Display.getCurrent().getActiveShell(), "Sexe manquant", "Le sexe du foetus" + personnes.get(index[nb - 1]).getNom() + " " + personnes.get(index[nb - 1]).getPrenom() + "n'est pas enregistré!");
												cell.setCellValue("A ENTRER");
											}

										}
									} else {
										if (personnes.get(index[nb - 1]).getSexe().equals("M")) {
											cell.setCellValue("Male");
										} else {
											cell.setCellValue("Femme");
										}
									}
								}
							}
							if (cell.getStringCellValue().contains("$stock")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && rangements.containsKey(index[nb - 1])) {
									if (rangements.get(index[nb - 1]) != null) {
										cell.setCellValue(rangements.get(index[nb - 1]).getValeur());
									}
								}
							}
							if (cell.getStringCellValue().equals("$numFeuille")) {
								cell.setCellValue("F" + fp.getIdFeuillePuce());
							}
						}
						if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
							evaluator.evaluateFormulaCell(cell);
						}

					}
				}
				// Get first sheet from the workbook
				HSSFSheet sheet1 = workbook.getSheetAt(1);
				// Iterate through each rows from first sheet
				Iterator<Row> rowIterator1 = sheet1.iterator();
				while (rowIterator1.hasNext()) {
					Row row = rowIterator1.next();

					// For each row, iterate through each columns
					Iterator<Cell> cellIterator = row.cellIterator();
					while (cellIterator.hasNext()) {

						Cell cell = cellIterator.next();
						if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
							if (cell.getStringCellValue().contains("$concentrationP")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 >= 0 && concentrations.containsKey(index[nb - 1]) && concentrations.get(index[nb - 1]) != null) {
									cell.setCellValue(concentrations.get(index[nb - 1]).getValeur().replace(".", ","));
								}
							}
							if (cell.getStringCellValue().contains("$concentrationSexe")) {
								int nb = Integer.parseInt(cell.getStringCellValue().substring(cell.getStringCellValue().length() - 1, cell.getStringCellValue().length()));
								if (nb - 1 < prelevements.size() && prelevements.containsKey(index[nb - 1]) && prelevements.get(index[nb - 1]) != null && prelevements.get(index[nb - 1]).getSecteur() != null && prelevements.get(index[nb - 1]).getSecteur().getLibelle() != null
										&& prelevements.get(index[nb - 1]).getSecteur().getLibelle().contains("rénatale")) {
									Champ cSexeFoetus = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tSexeFoetus", "Prel-" + prelevements.get(index[nb - 1]).getIdPrelevement());
									if (cSexeFoetus != null) {
										if (cSexeFoetus.getValeur().equals("M")) {
											cell.setCellValue("221,0");
										} else if (cSexeFoetus.getValeur().equals("F")) {
											cell.setCellValue("135,0");
										} else {
											MessageDialog.openError(Display.getCurrent().getActiveShell(), "Sexe manquant", "Le sexe du foetus" + personnes.get(index[nb - 1]).getNom() + " " + personnes.get(index[nb - 1]).getPrenom() + "n'est pas enregistré!");
											cell.setCellValue("A ENTRER");
										}

									}
								} else {
									if (personnes.containsKey(index[nb - 1])) {
										if (personnes.get(index[nb - 1]).getSexe().equals("M")) {
											cell.setCellValue(ApplicationContexte.CONCENTRATION_ADN_M);
										} else {
											cell.setCellValue(ApplicationContexte.CONCENTRATION_ADN_F);
										}
									}
								}

							}
						}
						if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
							evaluator.evaluateFormulaCell(cell);
						}
					}
				}

				// Get first sheet from the workbook
				HSSFSheet sheet2 = workbook.getSheetAt(2);
				// Iterate through each rows from first sheet
				Iterator<Row> rowIterator2 = sheet2.iterator();
				while (rowIterator2.hasNext()) {
					Row row = rowIterator2.next();

					// For each row, iterate through each columns
					Iterator<Cell> cellIterator = row.cellIterator();
					while (cellIterator.hasNext()) {
						Cell cell2 = cellIterator.next();
						if (cell2.getCellType() == Cell.CELL_TYPE_FORMULA) {
							evaluator.evaluateFormulaCell(cell2);
						}
					}
				}

				// Get first sheet from the workbook
				HSSFSheet sheet3 = workbook.getSheetAt(3);
				// Iterate through each rows from first sheet
				Iterator<Row> rowIterator3 = sheet3.iterator();
				while (rowIterator3.hasNext()) {
					Row row = rowIterator3.next();

					// For each row, iterate through each columns
					Iterator<Cell> cellIterator = row.cellIterator();
					while (cellIterator.hasNext()) {
						Cell cell3 = cellIterator.next();
						if (cell3.getCellType() == Cell.CELL_TYPE_FORMULA) {
							evaluator.evaluateFormulaCell(cell3);
						}
					}
				}

				file.close();
				FileOutputStream out = new FileOutputStream(fileout);
				workbook.write(out);
				out.close();
			}
			file.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		//
		// IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in,
		// TemplateEngineKind.Velocity);
		// Analyse analyse =
		// AnalyseServiceImpl.getInstance().getAnalyseByIdAnalyse(r.getAnalyse().getIdAnalyse());
		// Prelevement prelevement =
		// PrelevementServiceImpl.getInstance().getPrelevementById(analyse.getPrelevement().getIdPrelevement());
		// Personne personne =
		// PersonneServiceImpl.getInstance().getPersonneById(prelevement.getPersonne().getIdPersonne());
		// RenduBiomol rbm =
		// ResultatServiceImpl.getInstance().getRenduBioMolByIdResultat(r.getIdResultat());
		//
		// Champ dateExt =
		// PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("dateExtraction",
		// "Prel-" + prelevement.getIdPrelevement());
		// Champ typeADN =
		// PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tTypeADN",
		// "Prel-" + prelevement.getIdPrelevement());
		// SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		//
		//
		//
		// // 2) Create Java model context
		// IContext context = report.createContext();
		// context.put("personne", personne);
		// context.put("dateNaissance",
		// formatter.format(personne.getDateNaissance()));
		// if (typeADN != null) {
		// context.put("tTypeADN", typeADN.getValeur() + " d'ADN");
		// } else {
		// context.put("tTypeADN", "Extraction d'ADN");
		// }
		// if (dateExt.getValeur() != null) {
		// try {
		// context.put("dateExtraction",
		// formatter.format(formatter.parse(dateExt.getValeur())));
		// } catch (ParseException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// } else {
		// context.put("dateExtraction", "non rentrée");
		// }
		// context.put("dateRendu", formatter.format(r.getDateRendu()));
		// if (prelevement.getDateReception() == null) {
		// context.put("dateReception",
		// formatter.format(prelevement.getDatePrelevement()));
		// } else {
		// context.put("dateReception",
		// formatter.format(prelevement.getDateReception()));
		// }
		// if (prelevement.getDatePrelevement() == null) {
		// context.put("datePrelevement",
		// formatter.format(prelevement.getDateReception()));
		// } else {
		// context.put("datePrelevement",
		// formatter.format(prelevement.getDatePrelevement()));
		// }
		//
		// context.put("prelevement", prelevement);
		// context.put("resultat", r);
		// context.put("renduBiomol", rbm);
		//
		// List<VerifBiomolDoc> verifBiomolDocs = new
		// ArrayList<VerifBiomolDoc>();
		// List<VerifBiomol> verifBiomols =
		// ResultatServiceImpl.getInstance().getVerifBiomolByRenduBiomol(rbm.getIdRenduBioMol());
		// int i = 1;
		// for (VerifBiomol verifBiomol : verifBiomols) {
		// verifBiomolDocs.add(new VerifBiomolDoc(i, verifBiomol));
		// i++;
		// }
		// context.put("verifBiomolDocs", verifBiomolDocs);
		// context.put("analyse", analyse);
		//
		// if (!r.getCommentaire().contains("a permis de confirmer")) {
		// context.put("attention",
		// "1- Résultats strictement confidentiels ne pouvant être communiqués qu'au patient dans le cadre d'une consultation génétique.\r\n2- Toute analyse de génétique moléculaire comporte un risque d'erreur qui doit être expliqué aux patients et accepté.");
		// } else {
		// context.put(
		// "attention",
		// "1- Résultats ne permettant pas de borner le réarrangement et de préciser les points de cassure.\r\n[2- Résultats ne permettant pas de conclure que cette anomalie est responsable du phénotype.]\r\n3- Résultats strictement confidentiels ne pouvant être communiqués qu'au patient dans le cadre d'une consultation génétique.\r\n4- Toute analyse de génétique moléculaire comporte un risque d'erreur qui doit être expliqué aux patients et accepté.");
		// }
		//
		// // 3) Generate report by merging Java model with the ODT
		// OutputStream out = new FileOutputStream(fileout);
		// report.process(context, out);
		// File toto = new File(ApplicationContexte.REPERTOIRE_RESULTAT +
		// prelevement.getNumeroPrelevement() + "_" + personne.getNom() + "_" +
		// personne.getPrenom() + "_biomol_" +
		// formatter.format(r.getDateRendu()) + ".docx");
		// if (toto.exists()) {
		// nomFichierout = toto.getName();
		// }
		// }
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// } catch (XDocReportException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		return nomFichierOut;
	}
}
